[toc]
awk BEGIN模式、END模式
BEGIN模式
说明
BEGIN
模式在awk程序执行后,但尚未执行处理动作之前需要做的工作(定义变量)
作用
作用一 打印标题
文件 a.txt
内容如下
101,abc,CEO
102,def,CTO
103,qaz,COO
默认打印
$ awk '{print}' a.txt
101,abc,CEO
102,def,CTO
103,qaz,COO
使用 BEGIN
模式打印标题
$ awk 'BEGIN{print "ID","name","job"}{print}' a.txt
ID name job
101,abc,CEO
102,def,CTO
103,qaz,COO
作用二 做运算
示例1:计算1到100的和
$ awk 'BEGIN{for(i=1;i<=100;i++) sum+=i;print sum}'
5050
示例2:普通计算
# 加法
$ awk 'BEGIN{print 3+3}'
6
# 减法
$ awk 'BEGIN{print 3-3}'
0
# 乘法
$ awk 'BEGIN{print 3*3}'
9
# 除法
$ awk 'BEGIN{print 3/3}'
1
# 幂运算
$ awk 'BEGIN{print 3**3}'
27
# 取模
$ awk 'BEGIN{print 3%3}'
0
作用三 修改awk内置变量
-
record 字段
-
separator 分隔符
变量名 | 对应单词 | 含义 |
---|---|---|
FS | field separator | 字段分隔符,默认空格或 tab |
OFS | output field separator | 输出分隔符,默认空格 |
RS | record separator | 记录分隔符,默认换行符 \n |
ORS | output record separator | 输出记录分隔符 |
FS 指定字段分隔符
passwd.txt
文件内容如下
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
示例:以冒号为分隔符,打印文件第一列
- FS写法
- -F写法
$ awk 'BEGIN{FS=":"}{print $1}' passwd.txt
root
bin
daemon
$ awk -F: '{print $1}' passwd.txt
root
bin
daemon
OFS 指定输出分隔符
文件 a.txt
内容如下
1 2 3
a b c
D F 6
示例:打印文件第一列和第三列,以冒号为分隔符
- -v OFS写法
- BEGIN {OFS}写法
注意
-v OFS
写法的一个坑:当 print $0
的时候,-v OFS
会不生效
$ awk -v OFS=: '{print $0}' a.txt
1 2 3
a b c
D F 6
解决方法是在 print$0
前加一个 $1=$1
$ awk -v OFS=: '{$1=$1;print $0}' a.txt
1:2:3
a:b:c
D:F:6
$ awk -v OFS=: '{print $1,$3}' a.txt
1:3
a:c
D:6
$ awk 'BEGIN{OFS=":"}{print $1,$3}' a.txt
1:3
a:c
D:6
RS 指定记录分隔符,即指定以什么为分隔符,默认为 \n
passwd.txt
文件内容如下,文件默认以换行为记录分隔符
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
示例:将文件的记录分隔符指定为 /
,即指定文件以 /
为换行符
- -v RS写法
- BEGIN {RS}写法
$ awk -v RS=/ '{print $0}' passwd.txt
root:x:0:0:root:
root:
bin
bash
bin:x:1:1:bin:
bin:
sbin
nologin
daemon:x:2:2:daemon:
sbin:
sbin
nologin
$ awk 'BEGIN{RS="/"}{print $0}' passwd.txt
root:x:0:0:root:
root:
bin
bash
bin:x:1:1:bin:
bin:
sbin
nologin
daemon:x:2:2:daemon:
sbin:
sbin
nologin
ORS 指定输出记录分隔符
文件 a.txt
内容如下
1 2 3
a b c
D F 6
示例:将文件的输出记录分隔符指定为 /
- -v ORS写法
- BEGIN {ORS}写法
$ awk -v ORS="/" '{print $0}' a.txt
1 2 3/a b c/D F 6/
$ awk 'BEGIN{ORS="/"}{print $0}' a.txt
1 2 3/a b c/D F 6/
扩展 awk命令行参数
说明
-
ARGC
是命令 行参数数量 -
ARGV
是将命令行参数存到数组,元素由ARGC
指定,数组下标从0
开始
ARGC
说明
ARGC
是awk
的内置变量,表示 命令行参数的数量(Argument Count
),包括awk
命令本身- 在这个例子中,
awk
命令本身是第一个参数(awk
),但ARGC
在BEGIN
块中统计的是awk
处理的参数数量(不包括选项和程序代码) - 由于没有提供输入文件(如
awk 'BEGIN{print ARGC}' file.txt
),ARGC
的值为1
(仅包含awk
命令本身)
$ awk 'BEGIN{print ARGC}'
1
说明
- 在
BEGIN
块中,ARGC
已经计算完毕,但awk
还没有开始处理输入文件(如果有的话) - 这里的
1
和2
会被awk
视为输入文件(即使它们不是有效的文件名),但BEGIN
块在读取文件之前执行,所以ARGC
只计算参数数量
$ awk 'BEGIN{print ARGC}' 1 2
3
对比
- 如果运行
awk 'BEGIN{print ARGC}' file1 file2
(假设file1
和file2
存在),输出也是3
(awk
+file1
+file2
) - 如果运行
awk 'BEGIN{print ARGC}'
(无额外参数),输出是1
(只有awk
命令本身)
ARGV
说明
ARGV[0]
是awk
(命令本身)ARGV[1]
是1
(第一个额外参数)ARGV[2]
是2
(第二个额外参数)
$ awk 'BEGIN{print ARGV[0]}' 1 2
awk
$ awk 'BEGIN{print ARGV[1]}' 1 2
1
$ awk 'BEGIN{print ARGV[2]}' 1 2
2
END模式
说明
END
模式在 awk
读取完文件之后执行,主要作用为显示计算结果
作用 显示计算结果
示例1:统计 /etc/passwd
文件中前10行非登陆shell的个数
文件内容
$ head /etc/passwd
root:x:0:0:Super User:/root:/bin/bash
bin:x:1:1:bin:/bin:/usr/sbin/nologin
daemon:x:2:2:daemon:/sbin:/usr/sbin/nologin
adm:x:3:4:adm:/var/adm:/usr/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/usr/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/usr/sbin/nologin
operator:x:11:0:operator:/root:/usr/sbin/nologin
统计文件中 /sbin/nologin
的个数
$ head /etc/passwd | awk '/nologin/{i++}END{print i}'
6
示例2:统计 /etc/services
中空行数量
$ awk '/^$/{i++}END{print i}' /etc/services
17
示例3:统计nginx访问日志中访问量前10的IP
$ awk '{a[$1]++}END{for(i in a) print a[i],i}' /var/log/nginx/access.log|sort -nr|head
275 1.1.1.1
262 2.2.2.2
210 3.3.3.3
152 4.4.4.4
75 5.5.5.5
10 6.6.6.6
7 7.7.7.7
6 8.8.8.8
3 9.9.9.9
3 10.10.10.10